//
//  TestUI.m
//  Reservation
//
//  Created by Wai Man Chan on 5/3/14.
//  Copyright (c) 2014 CHAN, Wai Man. All rights reserved.
//

#import <XCTest/XCTest.h>
#import "RestaurantInfoViewController.h"
#import "CurrentAvailableViewController.h"
#import "AppoinmentViewController.h"
#import "LoginViewController.h"
#import "LoginModel.h"
#import "ReserveViewController.h"
#import "CurrentOrderModel.h"
#import <CoreLocation/CoreLocation.h>
#import "MenuEntityTableViewCell.h"
#import "AddCommentViewController.h"

@interface OrderBeacon : CLBeacon
@end
@implementation OrderBeacon
- (NSInteger)rssi { return -10; }
- (NSNumber *)major { return @2; }
- (NSNumber *)minor { return @1; }
@end

@interface A_TestUI : XCTestCase {
    UINavigationController *nav;
    UITabBarController *tab;
}
@end

@interface testGesture1 : UITapGestureRecognizer
@end
@implementation testGesture1
- (UIGestureRecognizerState)state { return UIGestureRecognizerStateBegan; }
@end

@interface testGesture2 : UITapGestureRecognizer
@end
@implementation testGesture2
- (UIGestureRecognizerState)state { return UIGestureRecognizerStateEnded; }
@end

@implementation A_TestUI

- (void)setUp
{
    [super setUp];
    // Put setup code here. This method is called before the invocation of each test method in the class.
    nav = [[UIApplication sharedApplication].delegate window].rootViewController;
    tab = nav.topViewController;
}

- (void)tearDown
{
    // Put teardown code here. This method is called after the invocation of each test method in the class.
    [super tearDown];
}

- (void)testUI:(void (^)())uiBlock {
    uiBlock();
    //500ms should cover everything from present animation to network
    [[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]];
}

- (void)wait {
    [[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:10]];
}

- (void)restoreState {
    [self testUI:^{
        [nav popToRootViewControllerAnimated:YES];
        tab.selectedIndex = 0;
    }];
}

- (void)_testReservation {
    [self restoreState];
    UICollectionViewController *gridView = [tab viewControllers][0];
    [self testUI:^{
        tab.selectedIndex = 0;
        UICollectionViewCell *cell = [gridView.collectionView cellForItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]];
        [gridView performSegueWithIdentifier:@"Selection" sender:cell];
    }];
    UITableViewController *tableCon = [nav topViewController];
    [self testUI:^{
        [tableCon tableView:tableCon.tableView didSelectRowAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]];
    }];
    for (int i = 3; i >= 0; i--) {
        [self testUI:^{
            RestaurantInfoViewController *vc = [nav topViewController];
            UISegmentedControl *sc = vc.segmentControl;
            sc.selectedSegmentIndex = i;
            [vc modeChange:sc];
        }];
    }
    [self testUI:^{
        [nav popViewControllerAnimated:YES];
    }];
    tableCon = [nav topViewController];
    [self testUI:^{
        [tableCon tableView:tableCon.tableView didSelectRowAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]];
    }];
    [self testUI:^{
        [nav popViewControllerAnimated:YES];
    }];
    tableCon = [nav topViewController];
    [self testUI:^{
        [tableCon tableView:tableCon.tableView didSelectRowAtIndexPath:[NSIndexPath indexPathForItem:2 inSection:0]];
    }];
    RestaurantInfoViewController *infoVC = [nav topViewController];
    [self testUI:^{
        [infoVC.basicInfoCon makeReservation:self];
    }];
    [self testUI:^{
        ReserveViewController *con = [nav topViewController];
        con.datePicker.date = [NSDate date];
        con.partySizeField.text = @"4";
        [con doneReserve:self];
    }];
    [self testUI:^{
        LoginViewController *vc = [[AccountModel shareInstance] loginVC];
        vc.usernameField.text = @"waimanchan";
        vc.passwordField.text = @"102385";
        [vc login:self];
        [vc dismissViewControllerAnimated:NO completion:^{
        }];
    }];
    XCTAssertTrue(true, "No Crash");
}

- (void)_testAvailable {
    [self restoreState];
    [self testUI:^{
        [nav popToRootViewControllerAnimated:YES];
    }];
    [self testUI:^{
        tab.selectedIndex = 1;
    }];
    CurrentAvailableViewController *con = [tab selectedViewController];
    [self testUI:^{
        [con.alertView textFieldAtIndex:0].text = @"4";
        [con alertView:con.alertView clickedButtonAtIndex:0];
        [con.alertView dismissWithClickedButtonIndex:0 animated:YES];
    }];
    
    
    [self restoreState];
    [self testUI:^{
        [nav popToRootViewControllerAnimated:YES];
    }];
    [self testUI:^{
        tab.selectedIndex = 1;
    }];
    con = [tab selectedViewController];
    [self testUI:^{
        [con.alertView textFieldAtIndex:0].text = @"4";
        [con alertView:con.alertView clickedButtonAtIndex:1];
        [con.alertView dismissWithClickedButtonIndex:1 animated:YES];
    }];
    [self testUI:^{
        [con tableView:con.tableView didSelectRowAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]];
    }];
    
    
    [self restoreState];
    [self testUI:^{
        [nav popToRootViewControllerAnimated:YES];
    }];
    [self testUI:^{
        tab.selectedIndex = 1;
    }];
    con = [tab selectedViewController];
    [self testUI:^{
        [con.alertView textFieldAtIndex:0].text = @"5";
        [con alertView:con.alertView clickedButtonAtIndex:1];
        [con.alertView dismissWithClickedButtonIndex:1 animated:YES];
    }];
    [self testUI:^{
        [con tableView:con.tableView didSelectRowAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]];
    }];
}

- (void)_testAppoinment {
    [self restoreState];
    [self testUI:^{
        tab.selectedIndex = 2;
    }];
    AppoinmentViewController *con = [tab selectedViewController];
    [self testUI:^{
        LoginViewController *vc = [[AccountModel shareInstance] loginVC];
        vc.usernameField.text = @"waimanchan";
        vc.passwordField.text = @"102385";
        [vc login:self];
        [vc dismissViewControllerAnimated:NO completion:^{
        }];
    }];
    [self testUI:^{
        [con.refreshControl beginRefreshing];
    }];
    for (int i = 0; i < [con.tableView numberOfRowsInSection:0]; i++) {
        [self testUI:^{
            [con tableView:con.tableView didSelectRowAtIndexPath:[NSIndexPath indexPathForItem:i inSection:0]];
        }];
        [self testUI:^{
            RestaurantInfoViewController *info = [nav topViewController];
            [info.basicInfoCon cancelReservation:self];
            [info.basicInfoCon alertView:NULL clickedButtonAtIndex:1];
        }];
    }
}

- (void)_testOrder {
    [self restoreState];
    CurrentOrderModel *model = [CurrentOrderModel shareModel];
    OrderBeacon *beacon = [OrderBeacon new];
    [self testUI:^{
        [model locationManager:NULL didRangeBeacons:@[beacon] inRegion:NULL];
    }];
    [self testUI:^{
        [tab setSelectedIndex:3];
    }];
    [self testUI:^{
        UITableViewController *con = [tab selectedViewController];
        [con tableView:con.tableView didSelectRowAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:1]];
        [con tableView:con.tableView didSelectRowAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]];
        [con tableView:con.tableView didSelectRowAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]];
        [con tableView:con.tableView didSelectRowAtIndexPath:[NSIndexPath indexPathForItem:1 inSection:0]];
        [con tableView:con.tableView didSelectRowAtIndexPath:[NSIndexPath indexPathForItem:2 inSection:0]];
        [con tableView:con.tableView didSelectRowAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:1]];
        [((MenuEntityTableViewCell *)[con.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]]) longPress:[testGesture1 new]];
        [((MenuEntityTableViewCell *)[con.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]]) longPress:[testGesture2 new]];
    }];
}

- (void)testUI {
    [self _testReservation];
    [self _testAvailable];
    [self _testAppoinment];
    [self _testOrder];
}

@end
